package main

import (
	"flag"
	"fmt"
	"log"
	"log/slog"
	"net"
	"os"
	"os/signal"
	"syscall"

	pb "gitee.com/jiebaiyou/demo-grpc/protos/user/v2"
	"gitee.com/jiebaiyou/demo-grpc/services/user/internal/app"
	"gitee.com/jiebaiyou/demo-grpc/services/user/service"
	"gitee.com/jiebaiyou/demo-grpc/shared/registry"
	clientv3 "go.etcd.io/etcd/client/v3"

	"google.golang.org/grpc"
)

var commit = "none"

func main() {
	slog.Info("版本信息", slog.String("commit", commit))

	// 定义命令行参数, 默认加载开发配置文件dev.yaml
	app.ConfigFile = flag.String("config", "config/yaml/dev.yaml", "path to config file")
	// 解析命令行参数
	flag.Parse()

	// 初始化全局配置
	_, err := app.InitConfig(*app.ConfigFile)
	if err != nil {
		slog.Error("初始化配置文件失败", slog.String("error", err.Error()))
		os.Exit(1)
	}

	err = app.InitLogger()
	if err != nil {
		slog.Error("初始化日志失败", slog.String("error", err.Error()))
		os.Exit(1)
	}

	// 创建ETCD客户端
	etcdClient, err := clientv3.New(clientv3.Config{
		Endpoints: app.Config.ETCD.ENDPOINTS,
		Username:  app.Config.ETCD.USERNAME,
		Password:  app.Config.ETCD.PASSWORD,
	})
	if err != nil {
		slog.Error("创建ETCD客户端失败", slog.String("error", err.Error()))
		os.Exit(1)
	}
	defer etcdClient.Close()

	// 创建服务实例
	userService := registry.NewService(app.Config.NAME, fmt.Sprintf("%s:%s", app.Config.IP, app.Config.PORT))

	// 创建服务注册器
	serviceRegister := registry.NewServiceRegister(etcdClient, userService)

	// 注册服务
	err = serviceRegister.Register()
	if err != nil {
		slog.Error("注册服务失败", slog.String("error", err.Error()))
		os.Exit(1)
	}

	listen, err := net.Listen("tcp", fmt.Sprintf(":%s", app.Config.PORT))
	if err != nil {
		log.Fatalf("监听失败: %v", err)
	}
	s := grpc.NewServer()
	pb.RegisterUserServiceServer(s, service.NewUserServer())
	slog.Info("用户服务正在运行", slog.String("address", fmt.Sprintf("%s:%s", app.Config.IP, app.Config.PORT)))

	// 优雅退出
	go func() {
		quit := make(chan os.Signal, 1)
		signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
		<-quit
		slog.Info("正在关闭服务...")
		slog.Info("注销已注册的服务", slog.String("service", userService.Name))
		err := serviceRegister.Deregister()
		if err != nil {
			slog.Error("注销服务失败", slog.String("error", err.Error()))
		}
		slog.Info("停止gRPC服务")
		s.GracefulStop()

		slog.Info("服务已关闭")
		os.Exit(0)
	}()

	if err := s.Serve(listen); err != nil {
		log.Fatalf("服务启动失败: %v", err)
	}
}
